package simpledb.execution;

import simpledb.common.DbException;
import simpledb.storage.Tuple;
import simpledb.storage.TupleDesc;
import simpledb.transaction.TransactionAbortedException;

import java.io.Serializable;
import java.util.NoSuchElementException;

/**
 * OpIterator 是所有 SimpleDB 操作符必须实现的迭代器接口。
 * 如果迭代器未打开，则任何方法都不应正常工作，并应抛出 IllegalStateException 异常。
 * 除了资源的分配和释放之外，open 方法还应该调用其子操作符的 open 方法；
 * 同样，在 close 方法中，一个操作符应该调用其子操作符的 close 方法。
 */
public interface OpIterator extends Serializable {

    /**
     * 打开该迭代器。在调用其他任何方法之前，必须先调用此方法。
     *
     * @throws DbException 当访问数据库出现问题时抛出
     */
    void open() throws DbException, TransactionAbortedException;

    /**
     * 判断是否还有更多元组可以返回。
     *
     * @return 如果还有更多元组则返回 true
     * @throws IllegalStateException 如果迭代器尚未打开
     */
    boolean hasNext() throws DbException, TransactionAbortedException;

    /**
     * 返回下一个元组（通常通过读取子操作符或访问方法实现）。
     *
     * @return 下一个元组
     * @throws NoSuchElementException 如果没有更多元组
     * @throws IllegalStateException 如果迭代器尚未打开
     */
    Tuple next() throws DbException, TransactionAbortedException, NoSuchElementException;

    /**
     * 将迭代器重置到起始位置。
     *
     * @throws DbException 当不支持 rewind 操作时抛出
     * @throws IllegalStateException 如果迭代器尚未打开
     */
    void rewind() throws DbException, TransactionAbortedException;

    /**
     * 返回与该迭代器关联的元组描述信息（TupleDesc）。
     *
     * @return 表示元组字段结构的 TupleDesc 对象
     */
    TupleDesc getTupleDesc();

    /**
     * 关闭该迭代器。当迭代器关闭后，调用 next()、hasNext() 或 rewind()
     * 应该抛出 IllegalStateException 异常。
     */
    void close();
}
